package educrypt.gui.ctr;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import educrypt.ciphers.playfair.Playfair;
import educrypt.commons.Alphabet;
import educrypt.commons.Global;
import educrypt.database.dao.AlphabetDAO;
import educrypt.exceptions.EduCryptException;
import educrypt.gui.util.GuiUtil;
import educrypt.gui.view.EditorAlphabetView;
import educrypt.gui.view.MainView;
import educrypt.i18n.Messages;

public class EditorAlphabetCtr implements ActionListener, ListSelectionListener {

	// View
	private EditorAlphabetView editorAlphabetView;

	// Model
	private AlphabetDAO alphabetDAO;
	private List<Alphabet> alphabets;

	public EditorAlphabetCtr(MainView view) {
		this.editorAlphabetView = view.getEditorAlphabetDialog();

		alphabetDAO = AlphabetDAO.getInstance();
		alphabets = new ArrayList<Alphabet>();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		try {
			String command = e.getActionCommand();
			if (command.equals(EditorAlphabetView.CIPHER_SELECTED)) {
				showStoredAlphabets();
				editorAlphabetView.enableAddButton(false);
			}
			if (command.equals(EditorAlphabetView.VALIDATE_ALPHABET)) {
				validateAlphabetSymbols();
				editorAlphabetView.enableAddButton(true);
			}
			if (command.equals(EditorAlphabetView.ADD_ALPHABET)) {
				addNewAlphabet();
				showStoredAlphabets();
			}
			if (command.equals(EditorAlphabetView.REMOVE_ALPHABET)) {
				removeAlphabet();
				showStoredAlphabets();
			}
		} catch (EduCryptException ex) {
			GuiUtil.showExceptionDialog((Component) editorAlphabetView,
					ex.getMessage());
		}
	}

	@Override
	public void valueChanged(ListSelectionEvent e) {
		int selectedAlphabetIndex = editorAlphabetView
				.getSelectedAlphabetIndex();
		if (selectedAlphabetIndex > -1) {
			Alphabet selectedAlphabet = alphabets.get(selectedAlphabetIndex);
			editorAlphabetView
					.setAlphabetNameToEdit(selectedAlphabet.getName());
			editorAlphabetView.setAlphabetSymbolsToEdit(selectedAlphabet
					.getSymbols());
		}
	}

	private void showStoredAlphabets() {
		List<Integer> ciphers = editorAlphabetView.getSelectedCiphers();
		alphabets = alphabetDAO.findByCiphers(ciphers);
		List<String> alphabetNames = new ArrayList<String>(alphabets.size());
		for (Alphabet alphabet : alphabets) {
			alphabetNames.add(alphabet.getName());
		}
		editorAlphabetView.showAlphabets(alphabetNames);
	}

	private void validateAlphabetSymbols() throws EduCryptException {
		String symbols = editorAlphabetView.getAlphabetSymbolsToEdit();
		String formattedSymbols = Alphabet.formatSymbols(symbols);
		List<Integer> selectedCiphers = editorAlphabetView.getSelectedCiphers();
		if (selectedCiphers.contains(Global.PLAYFAIR)) {
			formattedSymbols = Playfair.formatAlphabetSymbols(formattedSymbols);
		}
		editorAlphabetView.setAlphabetSymbolsToEdit(formattedSymbols);
	}

	private void addNewAlphabet() throws EduCryptException {
		String alphabetName = editorAlphabetView.getAlphabetNameToEdit();
		String alphabetSymbols = editorAlphabetView.getAlphabetSymbolsToEdit();
		if (alphabetName.equals("") || alphabetSymbols.equals("")) {
			throw new EduCryptException(
					Messages.getString("errAlphabetNotDefined"));
		}
		Alphabet newAlphabet = new Alphabet(alphabetName, alphabetSymbols);
		alphabetDAO
				.create(newAlphabet, editorAlphabetView.getSelectedCiphers());
	}

	private void removeAlphabet() {
		String alphabetName = editorAlphabetView.getSelectedAlphabet();
		alphabetDAO.delete(alphabetName);
	}

}
